package com.itheima.stock.service.impl;

import com.google.common.base.Strings;
import com.google.common.collect.Lists;
import com.itheima.stock.common.StockInfoConfig;
import com.itheima.stock.mapper.StockBlockRtInfoMapper;
import com.itheima.stock.mapper.StockBusinessMapper;
import com.itheima.stock.mapper.StockMarketIndexInfoMapper;
import com.itheima.stock.mapper.StockRtInfoMapper;
import com.itheima.stock.pojo.StockBlockRtInfo;
import com.itheima.stock.pojo.StockMarketIndexInfo;
import com.itheima.stock.pojo.StockRtInfo;
import com.itheima.stock.service.StockTimerService;
import com.itheima.stock.util.IdWorker;
import com.itheima.stock.util.ParserStockInfoUtil;
import lombok.extern.slf4j.Slf4j;
import org.joda.time.DateTime;
import org.joda.time.format.DateTimeFormat;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.web.client.RestTemplate;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

/**
 * 股票定时拉去数据服务实现
 */
@Service("stockTimerService")
@Slf4j
public class StockTimerServiceImpl implements StockTimerService {
    /**
     * 注入大盘配置数据bean
     */
    @Autowired
    private StockInfoConfig stockInfoConfig;

    /**
     * 注入模板对象
     */
    @Autowired
    private RestTemplate restTemplate;

    @Autowired
    private IdWorker idWorker;

    @Autowired
    private StockMarketIndexInfoMapper stockMarketIndexInfoMapper;

    @Autowired
    private StockRtInfoMapper stockRtInfoMapper;

    @Autowired
    private StockBusinessMapper stockBusinessMapper;

    @Autowired
    private ParserStockInfoUtil parserStockInfoUtil;

    @Autowired
    private StockBlockRtInfoMapper stockBlockRtInfoMapper;

    @Autowired
    private ThreadPoolTaskExecutor threadPoolTaskExecutor;



    /**
     * 获取国内大盘数据
     */
    @Override
    public void getInnerMarketInfo() {
        //拼接国内大盘url地址
        String innerUrl = stockInfoConfig.getMarketUrl() + String.join(",", stockInfoConfig.getInner());
        //发送请求获取大盘数据
        String respStr = restTemplate.getForObject(innerUrl, String.class);
        //解析数据,封装结果集
        if (Strings.isNullOrEmpty(respStr)) {
            log.info("未获取有效数据");
            return;
        }
        //定义正则
        String reg = "var hq_str_(.+)=\"(.+)\";";
        //编译正则,获取正则对象
        Pattern pattern = Pattern.compile(reg);
        //获取正则匹配器
        Matcher matcher = pattern.matcher(respStr);
        //搜集组装的大盘数据信息
        ArrayList<StockMarketIndexInfo> infos = new ArrayList<>();
        while (matcher.find()) {
            //大盘编码
            String marketCode=matcher.group(1);
            //其他信息
            String[] others=matcher.group(2).split(",");
            //大盘名称
            String marketName = others[0];
            //大盘点数
            BigDecimal curPoint = new BigDecimal(others[1]);
            //当前价格
            BigDecimal curPrice = new BigDecimal(others[2]);
            //振幅
            BigDecimal updownRate = new BigDecimal(others[3]);
            //成交量
            Long tradeCount = Long.valueOf(others[4]);
            //成交金额
            Long tradeVolume = Long.valueOf(others[5]);
            //组装实体对象
            StockMarketIndexInfo smi = StockMarketIndexInfo.builder()
                    .id(idWorker.nextId())
                    .markId(marketCode)
                    .curTime(new Date())
                    .markName(marketName)
                    .curPoint(curPoint)
                    .currentPrice(curPrice)
                    .updownRate(updownRate)
                    .tradeAccount(tradeCount)
                    .tradeVolume(tradeVolume)
                    .build();
            infos.add(smi);
        }
        log.info("共：{}条数据,内容为：{}",infos.size(),infos.toString());
        if (CollectionUtils.isEmpty(infos)) {
            log.info("");
            return;
        }
        //批量插入
        String curTime = DateTime.now().toString(DateTimeFormat.forPattern("yyyyMMddHHmmss"));
        log.info("采集的大盘数据：{},当前时间：{}",infos,curTime);

//        this.stockMarketIndexInfoMapper.insertBatch(infos);

    }

    /**
     * 测试获取A股股票信息
     */
    @Override
    public void getStockRtIndex() {
        //获取所有股票的id
        List<String> stockIds = stockBusinessMapper.findAllStockIds();
        //深圳:'0',上海:'6'
        stockIds = stockIds.stream().map(id->{
            id = id.startsWith("6") ? "sh"+ id : "sz"+ id;
            return id;
        }).collect(Collectors.toList());
        //将集合分组,每组20
        Lists.partition(stockIds,20).forEach(ids->{
           //每个分片的数据开启一个线程异步执行任务
            threadPoolTaskExecutor.execute(()->{
                //拼接获取A股信息的url地址
                String stockRtUrl = stockInfoConfig.getMarketUrl() + String.join(",", ids);
                //发送请求获取数据
                String result = restTemplate.getForObject(stockRtUrl, String.class);
                //解析获取股票数据
                List<StockRtInfo> list = parserStockInfoUtil.parser4StockOrMarketInfo(result, 3);
                //批量插入
                log.info("当前股票数据：{}",list);
//            stockRtInfoMapper.insertBatch(list);
            });

        });
    }

    /**
     * 测试获取板块数据
     */
    @Override
    public void getStockSectorRtIndex() {
        //组装url地址
        String blockUrl = stockInfoConfig.getBlockUrl();
        //获取响应数据
        String result = restTemplate.getForObject(blockUrl, String.class);
        //解析响应数据
        List<StockBlockRtInfo> infos = parserStockInfoUtil.parse4StockBlock(result);
        //分批处理
        Lists.partition(infos,20).forEach(items->{
           threadPoolTaskExecutor.execute(()->{
               //批量插入
               log.info("当前板块数据：{}",items);
//            stockBlockRtInfoMapper.insertBatch(items);
           });
        });
        try {
            TimeUnit.MINUTES.sleep(1);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }


}
